package com.example.interesting.distributed.lock.realize.aop;

import lombok.RequiredArgsConstructor;
import org.springframework.aop.support.AopUtils;
import org.springframework.aop.support.StaticMethodMatcher;
import org.springframework.core.annotation.AnnotatedElementUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author fyw
 * @version 1.0
 * @description: 方法匹配规则实现
 * @date 2024/3/10 14:28
 */
@RequiredArgsConstructor
public class DistributedLockPointMethodMatcher extends StaticMethodMatcher {
    private final Class<? extends Annotation> annotationClass;

    /**
     * 方法匹配规则
     */
    @Override
    public boolean matches(Method method, Class<?> targetClass) {
        //判断代理类方法是否存在入参注解，即DistriLockAnnotation
        if (AnnotatedElementUtils.hasAnnotation(method, annotationClass)) {
            return true;
        }
        //如果目标类为代理类，但是方法不存在注解直接返回
        if (Proxy.isProxyClass(targetClass)) {
            return false;
        }
        //获取目标类targetClass中与给定方法最匹配的、最具体的方法
        Method mostSpecificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
        return mostSpecificMethod != method && AnnotatedElementUtils.hasAnnotation(mostSpecificMethod, annotationClass);
    }
}
